package management;

import inputs.Input;

import java.util.LinkedList;
import java.util.List;

import javax.sound.midi.InvalidMidiDataException;

import midi.MidiOutParameter;

/**
 * Singleton class to handle Updates and Invalidations.
 * Keeps track of a list of inputs to invalidate and a list of inputs to update.
 * Functions to invalidate and update each list accordingly.
 * 
 * @author Dylan James
 *
 */
public class UpdateManager {
	private static UpdateManager instance;
	
	private List<Input> invalidateList;
	private List<Input> inputUpdateList;
	private List<MidiOutParameter> midiOutWriteList;
	
	/**
	 * @return An instance of the Update Manager.
	 */
	public static UpdateManager getUpdateManager()
	{
		if (instance == null)
		{
			instance = new UpdateManager();
		}
		
		return instance;
	}
	
	private UpdateManager()
	{
		invalidateList = new LinkedList<Input>();
		inputUpdateList = new LinkedList<Input>();
		midiOutWriteList = new LinkedList<MidiOutParameter>();
	}
	
	/**
	 * Starts managing the given Input. Invalidates on each invalidation call.
	 * @param input The Input to manage.
	 * @param update True if this Input should be updated at each Update call.
	 */
	public void Add(Input input, boolean update)
	{
		invalidateList.add(input);
		
		if (update)
		{
			inputUpdateList.add(input);
		}
	}
	
	public void Add(MidiOutParameter midiOutParam)
	{
		midiOutWriteList.add(midiOutParam);
	}
	
	/**
	 * Invalidates all managed Inputs.
	 */
	public void Invalidate()
	{
		for (Input input : invalidateList)
		{
			input.Invalidate();
		}
	}
	
	/**
	 * Updates all managed Inputs which were flagged to be updated.
	 */
	public void Update()
	{
		for (Input input : inputUpdateList)
		{
			input.UpdateInput();
		}
		
		for (MidiOutParameter midiOutParam : midiOutWriteList)
		{
			try {
				midiOutParam.Write();
			} catch (InvalidMidiDataException e) {
				e.printStackTrace();
			}
		}
		
	}
}
